package com.frank.demo.util;

import com.google.common.cache.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 内存缓存类
 * Created by zhy on 2018/5/8.
 */
public class GuavaUtils {

    private static final Logger LOG = LoggerFactory.getLogger(GuavaUtils.class);

    private GuavaUtils() {
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
//        GuavaUtils.put("ab", "test");
//        System.out.println(GuavaUtils.get("ab"));
//        TimeUnit.SECONDS.sleep(1);
//        GuavaUtils.delete("ab");
//        System.out.println(get("ab"));
    }

    //缓存接口这里是LoadingCache，LoadingCache在缓存项不存在时可以自动加载缓存
    private static final LoadingCache<String, Object> guavaCache
            //CacheBuilder的构造函数是私有的，只能通过其静态方法newBuilder()来获得CacheBuilder的实例
            = CacheBuilder.newBuilder()
            //设置并发级别为8，并发级别是指可以同时写缓存的线程数
            .concurrencyLevel(8)
            //设置写缓存后8秒钟过期
//                .expireAfterWrite(8, TimeUnit.SECONDS)
            //设置缓存容器的初始容量为10
            .initialCapacity(10)
            //设置缓存最大容量为100，超过100之后就会按照LRU最近虽少使用算法来移除缓存项
            .maximumSize(300)
            //设置要统计缓存的命中率
            .recordStats()
            //设置缓存的移除通知
//            .removalListener(new RemovalListener<Object, Object>() {
//                @Override
//                public void onRemoval(RemovalNotification<Object, Object> notification) {
//                    LOG.debug(notification.getKey() + " was removed, cause is " + notification.getCause());
//                }
//            })
            //build方法中可以指定CacheLoader，在缓存不存在时通过CacheLoader的实现自动加载缓存
            .build(new CacheLoader<String, Object>() {
                @Override
                public Object load(String key) throws Exception {
                    return null;
                }
            });

    @SuppressWarnings("unchecked")
    public static <T> T get(String key) {
        try {
            return (T) guavaCache.get(key);
        } catch (Exception e) {
            return null;
        }
    }

    public static void put(String key, Object value) {
        guavaCache.put(key, value);
    }

    public static void delete(String key) {
        guavaCache.invalidate(key);
    }

}
